package vn.edu.ptithcm.pim.controller;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

import vn.edu.ptithcm.pim.common.bean.TaskReportObject;
import vn.edu.ptithcm.pim.constant.Constants;
import vn.edu.ptithcm.pim.constant.UrlConstants;
import vn.edu.ptithcm.pim.dom.Employee;
import vn.edu.ptithcm.pim.dom.Project;
import vn.edu.ptithcm.pim.dom.TaskCategory;
import vn.edu.ptithcm.pim.dom.TaskPriority;
import vn.edu.ptithcm.pim.service.EmployeeService;
import vn.edu.ptithcm.pim.service.ProjectService;
import vn.edu.ptithcm.pim.service.TaskCategoryService;
import vn.edu.ptithcm.pim.service.TaskPriorityService;
import vn.edu.ptithcm.pim.service.TaskService;
import vn.edu.ptithcm.pim.service.TaskSeverityService;
import vn.edu.ptithcm.pim.service.TaskStatusService;
import vn.edu.ptithcm.pim.service.UserService;
import vn.edu.ptithcm.pim.util.ParamUtil;

@SuppressWarnings("deprecation")
public class ReportController extends SimpleFormController {
	private TaskService taskService;
	private UserService userService;
	private TaskSeverityService taskSeverityService;
	private TaskCategoryService taskCategoryService;
	private TaskPriorityService taskPriorityService;
	private TaskStatusService taskStatusService;
	private ProjectService projectService;
	private EmployeeService employeeService;

	Logger log = Logger.getLogger(ReportController.class);

	public ReportController() {
		super();
		setSessionForm(true);
		setCommandClass(Object.class);
		setFormView(UrlConstants.REPORT_URL);
		setSuccessView(UrlConstants.REPORT_URL);
	}

	@Override
	public void initBinder(HttpServletRequest request,
			ServletRequestDataBinder binder) throws Exception {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		binder.registerCustomEditor(Date.class, new CustomDateEditor(
				dateFormat, true));
	}

	@Override
	protected ModelAndView onSubmit(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException errors)
			throws Exception {
		return showForm(request, response, errors);
	}

	@SuppressWarnings("unchecked")
	@Override
	protected ModelAndView showForm(HttpServletRequest request,
			HttpServletResponse response, BindException errors)
			throws Exception {
		Map<String, Object> bean = new HashMap<String, Object>();
		if (userService.isSignedIn(request)) {
			String loginName = userService.getCurrentLogin(request);
			bean.put("user", userService.findByLoginName(loginName));
			bean.put("isSigned", true);
			bean.put("isAdmin", userService.isAdmin(loginName));
			bean.put(Constants.LOGIN_NAME, loginName);
			bean.put(Constants.USER_NAME, userService.getUsername(loginName));
			String visa = userService.getVisa(loginName);
			bean.put("visa", visa);

			int pnum = ParamUtil.getInteger(request, "pnum", 0);
			Project project = projectService.findByNumber(pnum);
			if (project != null) {
				bean.put("project", project);
				bean.put("tab", "report");

				List<TaskReportObject> categoriesReport = new ArrayList<TaskReportObject>();
				List<TaskCategory> categories = taskCategoryService
						.getCategoriesToReport(project.getProjectid());

				for (TaskCategory taskCategory : categories) {
					int open = projectService
							.countTasksByCategoryAndStatusType(
									taskCategory.getCategoryid(), "open",
									project.getProjectid());
					int closed = projectService
							.countTasksByCategoryAndStatusType(
									taskCategory.getCategoryid(), "closed",
									project.getProjectid());
					categoriesReport.add(new TaskReportObject(taskCategory
							.getName(), open, closed));
				}

				List<TaskReportObject> prioritiesReport = new ArrayList<TaskReportObject>();
				List<TaskPriority> priorities = taskPriorityService
						.getPrioritiesToReport(project.getProjectid());

				for (TaskPriority taskPriority : priorities) {
					int open = projectService
							.countTasksByPriorityAndStatusType(
									taskPriority.getPriorityid(), "open",
									project.getProjectid());
					int closed = projectService
							.countTasksByCategoryAndStatusType(
									taskPriority.getPriorityid(), "closed",
									project.getProjectid());
					prioritiesReport.add(new TaskReportObject(taskPriority
							.getName(), open, closed));
				}

				List<Employee> employees = employeeService
						.getMembersInProject(project.getProjectid());

				List<TaskReportObject> assignedToReport = new ArrayList<TaskReportObject>();
				List<TaskReportObject> reportersReport = new ArrayList<TaskReportObject>();

				for (Employee employee : employees) {
					int open = projectService
							.countTasksByAssignedToAndStatusType(
									employee.getVisa(), "open",
									project.getProjectid());
					int closed = projectService
							.countTasksByAssignedToAndStatusType(
									employee.getVisa(), "closed",
									project.getProjectid());
					assignedToReport.add(new TaskReportObject(employee
							.getVisa(), open, closed));

					int open_ = projectService
							.countTasksByReportedAndStatusType(
									employee.getVisa(), "open",
									project.getProjectid());
					int closed_ = projectService
							.countTasksByReportedAndStatusType(
									employee.getVisa(), "closed",
									project.getProjectid());
					reportersReport.add(new TaskReportObject(
							employee.getVisa(), open_, closed_));
				}
				bean.put("categoriesReport", categoriesReport);
				bean.put("prioritiesReport", prioritiesReport);
				bean.put("assignedToReport", assignedToReport);
				bean.put("reportersReport", reportersReport);
			}

		} else {
			int pnum = ParamUtil.getInteger(request, "pnum", 0);
			String params = "?pnum=" + pnum;
			String redirectLink = UrlConstants.REPORT_URL + UrlConstants.HTM
					+ params;
			request.getSession().setAttribute("redirectLink", redirectLink);
			response.sendRedirect(UrlConstants.HOME_PAGE_URL + UrlConstants.HTM);
		}
		request.setAttribute("bean", bean);
		return super.showForm(request, response, errors);
	}

	public TaskSeverityService getTaskSeverityService() {
		return taskSeverityService;
	}

	public void setTaskSeverityService(TaskSeverityService taskSeverityService) {
		this.taskSeverityService = taskSeverityService;
	}

	public TaskCategoryService getTaskCategoryService() {
		return taskCategoryService;
	}

	public ProjectService getProjectService() {
		return projectService;
	}

	public void setProjectService(ProjectService projectService) {
		this.projectService = projectService;
	}

	public TaskStatusService getTaskStatusService() {
		return taskStatusService;
	}

	public void setTaskStatusService(TaskStatusService taskStatusService) {
		this.taskStatusService = taskStatusService;
	}

	public void setTaskCategoryService(TaskCategoryService taskCategoryService) {
		this.taskCategoryService = taskCategoryService;
	}

	public TaskPriorityService getTaskPriorityService() {
		return taskPriorityService;
	}

	public void setTaskPriorityService(TaskPriorityService taskPriorityService) {
		this.taskPriorityService = taskPriorityService;
	}

	public TaskService getTaskService() {
		return taskService;
	}

	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public EmployeeService getEmployeeService() {
		return employeeService;
	}

	public void setEmployeeService(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}

}
